package com.classloading.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

import com.sun.tools.javap.JavapTask;

public class JavaCompilerUtil {
	
	public static final String path;
	
	static{
		final String osName = System.getProperty("os.name");
		if(osName.toUpperCase().contains("MAC")){
			path = "/Users/mazhi/Workspace/eclipse/eclipse_workspace/";
		}else{
			path = "/media/mazhi/sourcecode/workspace/projectjava5/";
		}
	}
	
	public static int compile(String sourcePath,String destPath) {
		com.sun.tools.javac.main.Main compiler = new com.sun.tools.javac.main.Main("javac");
		String[] args = new String[] { 
						    "-sourcepath",".",
							"-d", destPath, 
							sourcePath 
						};
		int rc = compiler.compile(args).exitCode;
		return rc;
	}
	
	public static void decompile(String destpath) {
		String[] args = new String[] { 
		    "-verbose",
		    destpath
		};
		JavapTask t = new JavapTask();
        int rc = t.run(args);
        System.exit(rc);
	}
	
	public static void run(String cmds[]){
		Process tps = null;
		InputStream is = null;
		try {
			ProcessBuilder builder = new ProcessBuilder();
			builder.redirectErrorStream(true);
			builder.command(cmds);
			tps = builder.start();
			is = tps.getInputStream();
			readBytes(is);
		} catch (Exception e) {
		} finally {
			if (tps != null)
				tps.destroyForcibly();
			if (is != null)
				try {
					is.close();
				} catch (IOException e) {
				}
		}
	}
	
	public static void readBytes(InputStream is) {
		InputStreamReader instr = null;
		try {
			instr = new InputStreamReader(is, "UTF-8");

			int ret_read = 0, index = 0;
			byte[] line = new byte[1024];

			Outer: for (;;) {
				if (!instr.ready()) {
					LockSupport.parkNanos(TimeUnit.NANOSECONDS.convert(300, TimeUnit.MILLISECONDS));
				}

				ret_read = instr.read();
				if (ret_read == -1) {
					break;
				}

				if (index >= line.length - 1) {
					byte[] dst = new byte[line.length * 2];
					System.arraycopy(line, 0, dst, 0, line.length - 1);
					line = dst;
				}

				switch (ret_read) {
				case '\r':
				case '\n':
					String lineStr = new String(line, 0, index);
					System.out.println(lineStr);
					index = 0;
					break;
				case '>':
					line[index++] = (byte) ret_read;
					lineStr = new String(line, 0, index);
					if (lineStr.endsWith(">")) {
						if (!instr.ready()) {
							break Outer;
						}
					}
					break;
				default:
					line[index++] = (byte) ret_read;
				}
			}
		} catch (IOException e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				if (instr != null)
					instr.close();
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}
		}
	}
	

}





